# -*- coding: utf-8 -*-
"""
Created on Mon Oct  8 14:32:52 2018

@author: luolei

生成变量相关图网络
"""
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
import json
import sys

sys.path.append('../')

from lib.data_analysis import *


def load_td_corr_file(method):
	"""载入计算所得的各变量之间时滞检测结果"""
	try:
		if method not in ['ccf', 'ie']:
			raise ValueError('Unknown method')
		else:
			fp = '../../data/runtime/{}_time_delay_correlation_results.json'.format(method)
			with open(fp, 'r', encoding = 'utf-8') as f:
				total_td_corr_results = json.load(f)
			
			bg_split_loc = None
			if method == 'ccf':
				bg_split_loc = ccf_bg_split_loc
			elif method == 'ie':
				bg_split_loc = ie_bg_split_loc
				
			return total_td_corr_results, bg_split_loc
	except Exception as e:
		raise RuntimeError('Error in loading td corr file: {}'.format(e))


if __name__ == '__main__':
	#%% 载入时滞相关性检测结果
	method = 'ccf'  # **手动设置该参数
	total_td_corr_results, bg_split_loc = load_td_corr_file(method)
	
	#%% 计算相关性强弱
	edges = []
	for col_x in total_td_corr_results.keys():
		td_corr_x_dict = total_td_corr_results[col_x]
		for col_y in td_corr_x_dict.keys():
			td_corr = td_corr_x_dict[col_y]
			
			# 计算背景均值和标准差
			bg_values = [abs(v) for k, v in td_corr.items() if abs(int(k)) > bg_split_loc]  # ** 使用绝对值
			mean, std = np.mean(bg_values), np.std(bg_values)
			sig_thres = mean + 3 * std  # 满足显著相关的阈值
			
			# 计算相关性作用强度
			chief_values = [abs(v) for k, v in td_corr.items() if abs(int(k)) <= bg_split_loc]  # ** 使用绝对值
			max_corr = max(chief_values)
			corr_strength = max_corr - sig_thres
			corr_strength = corr_strength if corr_strength > 0 else 0  # **非负数处理
			
			# 添加相关网络图的边
			edges.append([col_x, col_y, corr_strength])
			
			# todo: 返回最大相关对应的时滞
	
	#%% 绘制网络图并保存
	g = nx.DiGraph()
	for edge in edges:
		g.add_edge(edge[0], edge[1], weight = edge[2])
	
	edges = list(g.edges())
	weights = []
	for edge in edges:
		weights.append(g.get_edge_data(edge[0], edge[1])['weight'])
	
	pos = nx.spring_layout(g, iterations = 10)
	plt.figure('network', figsize = [10, 10])
	nx.draw_networkx_nodes(g, pos, node_color = 'w', node_size = 300)
	nx.draw_networkx_edges(g, pos, edge_width = 5 * weights, edge_color = weights, edge_cmap = plt.cm.Blues)
	nx.draw_networkx_labels(g, pos, font_size = 6, font_weight = 'normal')
	plt.tight_layout()
	plt.savefig('../../graph/graph_net.png', api = 450)
	

